package com.suwish.pc.ui.component;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import javax.swing.AbstractAction;
import javax.swing.JEditorPane;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

import com.suwish.device.util.Platform;
import com.suwish.pc.adb.CmdCallback;
import com.suwish.pc.util.StringUtils;

/**
 * 
 * 
 * 
 * @author Min
 *
 */
public class UIAdbTerminal extends JPanel implements CmdCallback{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private Process process = null;
//	private BufferedReader reader = null;
	private BufferedWriter writer = null;
	private JTextPane historyArea = new JTextPane();
	private JTextArea textArea = new JTextArea();
	private JScrollPane scrollPane = null;
	
	private Color noticeColor = new Color(34, 153, 57);
	private SimpleAttributeSet styles = new SimpleAttributeSet();
	private String[] historyCommands = new String[10]; //
	
//	private Window parent = null;
	private AbstractAction preference = null;
	public UIAdbTerminal(Window parent){
//		this.parent = parent;
		initUI();
		initEvent();
	}
	
	private void initEvent(){
		textArea.addKeyListener(new KeyListener() {			
			@Override
			public void keyTyped(KeyEvent e) {
			}
			
			@Override
			public void keyReleased(KeyEvent e) {
				if(e.getKeyCode() == KeyEvent.VK_ENTER){
					try{
						String command = textArea.getText();
						textArea.setText("");
						textArea.requestFocus();
						addHistory(command);
						sendCommand(command);
					}catch(Exception ex){
						ex.toString();
					}
				}
			}
			@Override
			public void keyPressed(KeyEvent e) {
			}
		});
		preference = new AbstractAction() {
			private static final long serialVersionUID = 1L;
			@Override
			public void actionPerformed(ActionEvent e) {
				
			}
		};
		final JPopupMenu menu = new JPopupMenu();
		JMenuItem terminalItem = new JMenuItem("Terminal");
		menu.add(terminalItem);
		terminalItem.setEnabled(false);
		terminalItem.addActionListener(preference);
		historyArea.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseReleased(MouseEvent e) {
				if(!e.isPopupTrigger()) return;
				menu.show(historyArea, e.getX(), e.getY());
			}
			
		});
	}
	private void initUI(){
		setLayout(new BorderLayout(0, 0));
		add(scrollPane = new JScrollPane(historyArea), BorderLayout.CENTER);
		historyArea.setEditable(false);
		textArea.setPreferredSize(new Dimension(getWidth(), 120));
		add(new JScrollPane(textArea), BorderLayout.SOUTH);
		textArea.requestFocus();
		textArea.setEditable(false);
	}
	
	private void sendCommand(String command){
		try{
			String cmd = (command.indexOf("$") != -1 || command.indexOf("#") != -1) ? command.substring(3) : command;
			writer.write(cmd);
			writer.flush();
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
	private synchronized void addMessage(Document doc, String cmd) throws BadLocationException{
		doc.insertString(doc.getLength(), cmd, styles);
		int length = historyArea.getStyledDocument().getLength();
		historyArea.setCaretPosition(length);
		JScrollBar scrollBar = scrollPane.getVerticalScrollBar();
		scrollBar.setValue(scrollBar.getMaximum());
	}
	private void addHistory(String command) throws BadLocationException{
		StyleConstants.setFirstLineIndent(styles, 0);
		StyleConstants.setForeground(styles, Color.BLACK);
		StyleConstants.setBold(styles, false);
		addMessage(historyArea.getDocument(), command + Platform.getLineSeparator());
	}
	
	public void addNoticeMessage(String command) throws BadLocationException{
		StyleConstants.setFirstLineIndent(styles, 10);
		StyleConstants.setForeground(styles, noticeColor);
		StyleConstants.setBold(styles, true);
		addMessage(historyArea.getDocument(), command + Platform.getLineSeparator());
	}
	public void addErrorMessage(String command) throws BadLocationException{
		StyleConstants.setFirstLineIndent(styles, 10);
		StyleConstants.setForeground(styles, Color.RED);
		StyleConstants.setBold(styles, false);
		addMessage(historyArea.getDocument(), command + Platform.getLineSeparator());
	}
	public void setProcess(final Process process, final String desc){
		this.process = process;
		new Thread(){
			public void run(){
				historyArea.setText("");
				setReader(new BufferedReader(new InputStreamReader(process.getInputStream())));
				setWriterr(new BufferedWriter(new OutputStreamWriter(process.getOutputStream())));
				textArea.setEditable(true);
				try{
					addNoticeMessage("Connect " + desc + " sucess!");
				}catch(Exception ex){
					ex.printStackTrace();
				}
				try{
					process.waitFor();
				}catch(Exception ex){
					ex.printStackTrace();
				}
				try{
					addErrorMessage("Device " + desc + " disconnect!");
				}catch(Exception ex){
					ex.printStackTrace();
				}
				textArea.setEditable(false);
			}
		}.start();
	}
	
	public void setReader(final BufferedReader reader){
		new Thread(){
			public void run(){
				String buffer = null;
				try {
					while((buffer = reader.readLine()) != null){
//						System.err.println("reader :" + buffer);
						if(StringUtils.isEmpty(buffer)) continue;
						addHistory(buffer);
						buffer = null;
					}
				} catch (IOException e) {
					e.printStackTrace();
				} catch(Exception e){
					e.printStackTrace();
				}
			}
		}.start();
	}
	
	public void setWriterr(BufferedWriter writer){
		this.writer = writer;
	}
	public AbstractAction getAction(){
		return preference;
	}
	
	public boolean isRunning(){
		return process != null;
	}
	/**
	 * 
	 * 
	 * 
	 */
	public void dispose(){
		if(process == null) return;
		try{			
//			writer.close();
//			reader.close();
			process.destroy();
			process = null;
			textArea.setEditable(false);
		}catch(Exception ex){
			ex.toString();
		}
	}
	@Override
	public void callBack(String message) {
		try{
			addErrorMessage(message + Platform.getLineSeparator());
		}catch(Exception ex){
			ex.printStackTrace();
		}
		
	}
}
